package cn.lg.soar.common.util.data;

import cn.lg.soar.common.util.DatetimeUtil;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 数据转换工具
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public interface DataUtil {

    char[] HEXCHARS = "0123456789abcdef".toCharArray();
    int[] CHAR2INTL = new int[]{
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1,
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
            -1, -1, -1, -1, -1, -1, -1,
            0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1,
            0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    };
    int[] CHAR2INTH = new int[]{
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1,
            0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90,
            -1, -1, -1, -1, -1, -1, -1,
            0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
            -1, -1, -1, -1, -1, -1,
            0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0
    };

    Base64.Decoder BASE64DE = Base64.getDecoder();
    Base64.Encoder BASE64EN = Base64.getEncoder();
    Base64.Decoder BASE64URLDE = Base64.getUrlDecoder();
    Base64.Encoder BASE64URLEN = Base64.getUrlEncoder();

    /**
     * byte数组转16进制字符串
     * @param bytes
     */
    static String byteToHex(byte ...bytes){
        char[] chars = new char[ bytes.length << 1 ];
        for (int i = 0; i < bytes.length; i++) {
            byte b = bytes[i];
            int index = i << 1;
            chars[ index ] = HEXCHARS[ (b & 0xF0) >>> 4 ];
            chars[ index + 1 ] = HEXCHARS[ b & 0x0F ];
        }
        return String.valueOf(chars);
    }

    /**
     * 十六进制转byte数组
     * @param hex
     * @return
     */
    static byte[] hexToBytes(String hex){
        if(hex.length() % 2 == 1){
            hex = "0" + hex;
        }
        char[] chars = hex.toCharArray();
        byte[] bytes = new byte[ chars.length >>> 1 ];
        for(int i = 0; i < chars.length; i += 2){
            int h = CHAR2INTH[chars[ i ]];
            int l = CHAR2INTL[chars[ i + 1 ]];
            bytes[ i >>> 1 ] = (byte) (h | l);
        }
        return bytes;
    }

    /**
     * byte数组转 Url Base64
     * @param bytes
     * @return
     */
    static String byteToUrlBase64(byte ...bytes){
        return BASE64URLEN.encodeToString(bytes).replaceAll("=", "");
    }

    /**
     * 字符串转 Url Base64
     * @param jsonString
     * @return
     */
    static Object byteToUrlBase64(String jsonString) {
        return byteToUrlBase64(jsonString.getBytes());
    }

    /**
     * UrlBase64 转byte数组
     * @param base64
     * @return
     */
    static byte[] urlBase64ToByte(String base64){
        return BASE64URLDE.decode(base64);
    }

    /**
     * byte数组转 Base64
     * @param bytes
     * @return
     */
    static String byteToBase64(byte ...bytes){
        return BASE64EN.encodeToString(bytes);
    }

    /**
     * 字符串转 Base64
     * @param data
     * @return
     */
    static String byteToBase64(String data) {
        return byteToBase64(data.getBytes());
    }

    /**
     * Base64 转byte数组
     * @param base64
     * @return
     */
    static byte[] base64ToByte(String base64){
        return BASE64DE.decode(base64);
    }

    /**
     * long 转 Base64
     * @param l
     * @return
     */
    static String longToBase64(long l){
        return Base64.getEncoder().encodeToString(longToBytes(l));
    }

    /**
     * long数组 转 Base64
     * @param ids
     * @return
     */
    static String longsToBase64(long...ids) {
        byte[] bytes = new byte[ids.length << 3];
        int i = 0;
        for (long id : ids) {
            byte[] bs = longToBytes(id);
            for (byte b : bs) {
                bytes[i++] = b;
            }
        }
        return byteToUrlBase64(bytes);
    }

    /**
     * Base64 转 long数组
     * @param str
     * @return
     */
    static long[] base64ToLongs(String str) {
        byte[] bytes = urlBase64ToByte(str);
        int length = bytes.length >> 3;
        long[] longs = new long[length];
        int j = 0;
        for (int i = 0; i < length; i++) {
            byte[] bs = new byte[8];
            for (int i1 = 0; i1 < bs.length; i1++) {
                bs[i1] = bytes[j++];
            }
            longs[i] = byteToLong(bs);
        }
        return longs;
    }

    /**
     * byte数组 转 long
     * @param bytes
     * @return
     */
    static long byteToLong(byte ...bytes) {
        switch (bytes.length) {
            case 8: return ((bytes[ 0 ] & 0xffL) << 56)
                    | ((bytes[ 1 ] & 0xffL) << 48)
                    | ((bytes[ 2 ] & 0xffL) << 40)
                    | ((bytes[ 3 ] & 0xffL) << 32)
                    | ((bytes[ 4 ] & 0xffL) << 24)
                    | ((bytes[ 5 ] & 0xffL) << 16)
                    | ((bytes[ 6 ] & 0xffL) << 8)
                    | (bytes[ 7 ] & 0xffL);
            case 7: return ((bytes[ 0 ] & 0xffL) << 48)
                    | ((bytes[ 1 ] & 0xffL) << 40)
                    | ((bytes[ 2 ] & 0xffL) << 32)
                    | ((bytes[ 3 ] & 0xffL) << 24)
                    | ((bytes[ 4 ] & 0xffL) << 16)
                    | ((bytes[ 5 ] & 0xffL) << 8)
                    | (bytes[ 6 ] & 0xffL);
            case 6: return ((bytes[ 0 ] & 0xffL) << 40)
                    | ((bytes[ 1 ] & 0xffL) << 32)
                    | ((bytes[ 2 ] & 0xffL) << 24)
                    | ((bytes[ 3 ] & 0xffL) << 16)
                    | ((bytes[ 4 ] & 0xffL) << 8)
                    | (bytes[ 5 ] & 0xffL);
            case 5: return ((bytes[ 0 ] & 0xffL) << 32)
                    | ((bytes[ 1 ] & 0xffL) << 24)
                    | ((bytes[ 2 ] & 0xffL) << 16)
                    | ((bytes[ 3 ] & 0xffL) << 8)
                    | (bytes[ 4 ] & 0xffL);
            case 4: return ((bytes[ 0 ] & 0xffL) << 24)
                    | ((bytes[ 1 ] & 0xffL) << 16)
                    | ((bytes[ 2 ] & 0xffL) << 8)
                    | (bytes[ 3 ] & 0xffL);
            case 3: return ((bytes[ 0 ] & 0xffL) << 16)
                    | ((bytes[ 1 ] & 0xffL) << 8)
                    | (bytes[ 2 ] & 0xffL);
            case 2: return ((bytes[ 0 ] & 0xffL) << 8)
                    | (bytes[ 1 ] & 0xffL);
            case 1: return (bytes[ 0 ] & 0xffL);
            default: break;
        }
        return 0L;
    }

    /**
     * long 转 byte数组
     * @param l
     * @return
     */
    static byte[] longToBytes(long l){
        byte[] result = new byte[8];
        result[7] = (byte)(l & 0xFF);
        l >>= 8;
        result[6] = (byte)(l & 0xFF);
        l >>= 8;
        result[5] = (byte)(l & 0xFF);
        l >>= 8;
        result[4] = (byte)(l & 0xFF);
        l >>= 8;
        result[3] = (byte)(l & 0xFF);
        l >>= 8;
        result[2] = (byte)(l & 0xFF);
        l >>= 8;
        result[1] = (byte)(l & 0xFF);
        l >>= 8;
        result[0] = (byte)(l & 0xFF);
        return result;
    }

    /**
     * byte数组 转 int
     * @param bytes
     * @return
     */
    static int byteToInt(byte ...bytes) {
        switch (bytes.length) {
            case 4: return ((bytes[ 0 ] & 0xff) << 24)
                    | ((bytes[ 1 ] & 0xff) << 16)
                    | ((bytes[ 2 ] & 0xff) << 8)
                    | (bytes[ 3 ] & 0xff);
            case 3: return ((bytes[ 0 ] & 0xff) << 16)
                    | ((bytes[ 1 ] & 0xff) << 8)
                    | (bytes[ 2 ] & 0xff);
            case 2: return ((bytes[ 0 ] & 0xff) << 8)
                    | (bytes[ 1 ] & 0xff);
            case 1: return (bytes[ 0 ] & 0xff);
            default: break;
        }
        return 0;
    }

    /**
     * int 转 byte数组
     * @param i
     * @return
     */
    static byte[] intToBytes(int i){
        byte[] result = new byte[4];
        result[3] = (byte)(i & 0xFF);
        i >>= 8;
        result[2] = (byte)(i & 0xFF);
        i >>= 8;
        result[1] = (byte)(i & 0xFF);
        i >>= 8;
        result[0] = (byte)(i & 0xFF);
        return result;
    }

    /**
     * 根据日期计算年龄
     * @param date
     * @return
     */
    static long dateToAge(LocalDateTime date){
        return LocalDateTime.now().until(date, ChronoUnit.YEARS);
    }
    static long dateToAge(String date, String format) {
        return dateToAge(DatetimeUtil.from(date, format));
    }
    static long dateToAge(String date) {
        return dateToAge(DatetimeUtil.from(date));
    }

    /**
     * 字节单位转换
     * @param size 文件字节数
     * @param precision 精度
     * @return
     */
    static String fileSizeFormat(long size, int precision){
        if(size < 1024){
            return size+"B";
        }
        if(size < 1048576){
            return String.format("%."+precision+"fKB", size/1024.0D);
        }
        if(size < 1073741824){
            return String.format("%."+precision+"fMB", size/1048576.0D);
        }
        if(size < 1099511627776L){
            return String.format("%."+precision+"fGB", size/1073741824.0D);
        }
        if(size < 1125899906842624L){
            return String.format("%."+precision+"fTB", size/1099511627776.0D);
        }
        if(size < 1152921504606846976L){
            return String.format("%."+precision+"fPB", size/1125899906842624.0D);
        }
        return String.format("%."+precision+"fEB", size/1152921504606846976.0D);
    }

    /**
     * 字节单位转换
     * @param size 文件字节数
     * @return
     */
    static String fileSizeFormat(long size){
        return fileSizeFormat(size, 2);
    }

    /**
     * 字节单位转换
     * @param bytes 字节数组
     * @param precision 精度
     * @return
     */
    static String fileSizeFormat(byte[] bytes, int precision){
        return fileSizeFormat(bytes.length, precision);
    }

    /**
     * 字节单位转换
     * @param bytes 字节数组
     * @return
     */
    static String fileSizeFormat(byte[] bytes){
        return fileSizeFormat(bytes.length, 2);
    }

    /**
     * 数组转 Set
     * @param ts
     * @param <T>
     * @return
     */
    @SafeVarargs
    static <T> Set<T> arrayToSet(T ...ts) {
        if (ts == null) {
            return Collections.emptySet();
        }
        Set<T> set = new HashSet<>(ts.length);
        for (T t : ts) {
            set.add(t);
        }
        return set;
    }

    /**
     * 数组转 List
     * @param ts
     * @param <T>
     * @return
     */
    @SafeVarargs
    static <T> List<T> arrayToList(T ...ts) {
        if (ts == null) {
            return Collections.emptyList();
        }
        List<T> list = new ArrayList<>(ts.length);
        for (T t : ts) {
            list.add(t);
        }
        return list;
    }

    /**
     * 数组转map
     * @param key
     * @param value
     * @param ts
     * @return
     * @param <T>
     * @param <K>
     * @param <V>
     */
    @SafeVarargs
    static <T, K, V> Map<K, V> arrayToMap(Function<T, K> key, Function<T, V> value, T ...ts) {
        if (ts == null) {
            return Collections.emptyMap();
        }
        Map<K, V> map = new HashMap<>(ts.length);
        for (T t : ts) {
            map.put(key.apply(t), value.apply(t));
        }
        return map;
    }

    /**
     * 数组转map
     * @param key
     * @param ts
     * @return
     * @param <T>
     * @param <K>
     */
    @SafeVarargs
    static <T, K> Map<K, T> arrayToMap(Function<T, K> key, T ...ts) {
        return arrayToMap(key, x -> x, ts);
    }

    /**
     * 集合转map
     * @param key
     * @param value
     * @param ts
     * @return
     * @param <T>
     * @param <K>
     * @param <V>
     */
    static <T, K, V> Map<K, V> collectionToMap(Function<T, K> key, Function<T, V> value, Collection<T> ts) {
        if (ts == null) {
            return Collections.emptyMap();
        }
        Map<K, V> map = new HashMap<>(ts.size());
        for (T t : ts) {
            map.put(key.apply(t), value.apply(t));
        }
        return map;
    }

    /**
     * 集合转map
     * @param key
     * @param ts
     * @return
     * @param <T>
     * @param <K>
     */
    static <T, K> Map<K, T> collectionToMap(Function<T, K> key, Collection<T> ts) {
        return collectionToMap(key, x -> x, ts);
    }

    /**
     * 集合转数组
     * @param list
     * @param <T>
     * @return
     */
    static <T>T[] collectionToArray(Collection<T> list) {
        if (list == null) {
            return (T[]) Array.newInstance(Object.class, 0);
        }
        return (T[]) list.toArray();
    }


    /**
     * 遍历数据
     * @param value
     * @param consumer
     */
    static void forEach(Object value, Consumer<Object> consumer) {
        if (value.getClass().isArray()) {
            Object[] array = (Object[]) value;
            for (Object o : array) {
                consumer.accept(o);
            }
            return;
        }
        if (value instanceof Iterable) {
            Iterable<?> iterable = (Iterable<?>) value;
            iterable.forEach(consumer);
            return;
        }
        consumer.accept(value);
    }

    /**
     * 转为 String 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static String toString(Object value, String defVal) {
        if (value == null) {
            return defVal;
        }
        return value.toString();
    }

    /**
     * 转为 String 类型值
     * @param value 值
     * @return
     */
    static String toString(Object value) {
        return toString(value, null);
    }

    /**
     * 转为 Character 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static Character toCharacter(Object value, Character defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof Character) {
            return (Character) value;
        }
        return value.toString().charAt(0);
    }

    /**
     * 转为 Character 类型值
     * @param value 值
     * @return
     */
    static Character toCharacter(Object value) {
        return toCharacter(value, null);
    }

    /**
     * 转为 Boolean 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static Boolean toBoolean(Object value, Boolean defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof Boolean) {
            return (Boolean) value;
        }
        try {
            return Boolean.parseBoolean(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 Boolean 类型值
     * @param value 值
     * @return
     */
    static Boolean toBoolean(Object value) {
        return toBoolean(value, null);
    }

    /**
     * 转为 Long 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static Long toLong(Object value, Long defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof Long) {
            return (Long) value;
        }
        try {
            return Long.parseLong(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 Long 类型值
     * @param value 值
     * @return
     */
    static Long toLong(Object value) {
        return toLong(value, null);
    }

    /**
     * 转为 Integer 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static Integer toInteger(Object value, Integer defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof Integer) {
            return (Integer) value;
        }
        try {
            return Integer.parseInt(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 Integer 类型值
     * @param value 值
     * @return
     */
    static Integer toInteger(Object value) {
        return toInteger(value, null);
    }

    /**
     * 转为 Short 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static Short toShort(Object value, Short defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof Short) {
            return (Short) value;
        }
        try {
            return Short.parseShort(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 Short 类型值
     * @param value 值
     * @return
     */
    static Short toShort(Object value) {
        return toShort(value, null);
    }

    /**
     * 转为 Byte 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static Byte toByte(Object value, Byte defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof Byte) {
            return (Byte) value;
        }
        try {
            return Byte.parseByte(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 Byte 类型值
     * @param value 值
     * @return
     */
    static Byte toByte(Object value) {
        return toByte(value, null);
    }

    /**
     * 转为 Float 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static Float toFloat(Object value, Float defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof Float) {
            return (Float) value;
        }
        try {
            return Float.parseFloat(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 Float 类型值
     * @param value 值
     * @return
     */
    static Float toFloat(Object value) {
        return toFloat(value, null);
    }

    /**
     * 转为 Double 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static Double toDouble(Object value, Double defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof Double) {
            return (Double) value;
        }
        try {
            return Double.parseDouble(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 Double 类型值
     * @param value 值
     * @return
     */
    static Double toDouble(Object value) {
        return toDouble(value, null);
    }

    /**
     * 转为 BigDecimal 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static BigDecimal toBigDecimal(Object value, BigDecimal defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        try {
            return new BigDecimal(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 BigDecimal 类型值
     * @param value 值
     * @return
     */
    static BigDecimal toBigDecimal(Object value) {
        return toBigDecimal(value, null);
    }

    /**
     * 转为 BigInteger 类型值
     * @param value 值
     * @param defVal 默认值
     * @return
     */
    static BigInteger toBigInteger(Object value, BigInteger defVal) {
        if (value == null) {
            return defVal;
        }
        if (value instanceof BigInteger) {
            return (BigInteger) value;
        }
        try {
            return new BigInteger(value.toString());
        } catch (RuntimeException e) {
            return defVal;
        }
    }

    /**
     * 转为 BigInteger 类型值
     * @param value 值
     * @return
     */
    static BigInteger toBigInteger(Object value) {
        return toBigInteger(value, null);
    }

    /**
     * 转换数据为指定值
     * @param javaType 转换结果类型
     * @param value 原值
     * @param defVal 默认值
     * @param <T>
     * @return
     */
    static <T> T to(Class<T> javaType, Object value, T defVal) {
        if (value == null) {
            return defVal;
        }
        if (javaType.isInstance(value)) {
            return (T) value;
        }
        if (Integer.class.isAssignableFrom(javaType)) {
            return (T) toInteger(value, (Integer) defVal);
        }
        if (String.class.isAssignableFrom(javaType)) {
            return (T) toString(value, (String) defVal);
        }
        if (Long.class.isAssignableFrom(javaType)) {
            return (T) toLong(value, (Long) defVal);
        }
        if (Boolean.class.isAssignableFrom(javaType)) {
            return (T) toBoolean(value, (Boolean) defVal);
        }
        if (BigDecimal.class.isAssignableFrom(javaType)) {
            return (T) toBigDecimal(value, (BigDecimal) defVal);
        }
        if (Double.class.isAssignableFrom(javaType)) {
            return (T) toDouble(value, (Double) defVal);
        }
        if (Float.class.isAssignableFrom(javaType)) {
            return (T) toFloat(value, (Float) defVal);
        }
        if (Character.class.isAssignableFrom(javaType)) {
            return (T) toCharacter(value, (Character) defVal);
        }
        if (Byte.class.isAssignableFrom(javaType)) {
            return (T) toByte(value, (Byte) defVal);
        }
        if (Short.class.isAssignableFrom(javaType)) {
            return (T) toShort(value, (Short) defVal);
        }
        if (BigInteger.class.isAssignableFrom(javaType)) {
            return (T) toBigInteger(value, (BigInteger) defVal);
        }
        if (Enum.class.isAssignableFrom(javaType)) {
            try {
                return (T) Enum.valueOf((Class<? extends Enum>) javaType, value.toString());
            } catch (RuntimeException e) {
                return defVal;
            }
        }
        return defVal;
    }

    /**
     * 转换数据为指定值
     * @param javaType 转换结果类型
     * @param value 原值
     * @param <T>
     * @return
     */
    static <T> T to(Class<T> javaType, Object value) {
        return to(javaType, value, null);
    }

    
    /**
     * 是有值的
     * @param value
     * @return
     */
    static boolean isValuable(Object value) {
        if (value == null) {
            return false;
        }
        if (value instanceof CharSequence) {
            return ((CharSequence) value).length() != 0;
        }
        if (value instanceof Collection) {
            return !((Collection<?>) value).isEmpty();
        }
        if (value instanceof Map) {
            return !((Map<?,?>) value).isEmpty();
        }
        if (value.getClass().isArray()) {
            return ((Object[]) value).length != 0;
        }
        if (value instanceof Iterable) {
            return ((Iterable<?>) value).iterator().hasNext();
        }
        return true;
    }

    /**
     * 是有值的
     * @param value
     * @return
     */
    static boolean isValuable(Number value) {
        return value != null;
    }

    /**
     * 是有值的
     * @param value
     * @return
     */
    static boolean isValuable(Boolean value) {
        return value != null;
    }

    /**
     * 是有值的
     * @param value
     * @return
     */
    static boolean isValuable(CharSequence value) {
        return value != null && value.length() != 0;
    }

    /**
     * 是有值的
     * @param value
     * @return
     */
    static <T>boolean isValuable(T[] value) {
        return value != null && value.length != 0;
    }

    /**
     * 是有值的
     * @param value
     * @return
     */
    static boolean isValuable(Collection<?> value) {
        return value != null && !value.isEmpty();
    }

    /**
     * 是有值的
     * @param value
     * @return
     */
    static boolean isValuable(Map<?, ?> value) {
        return value != null && !value.isEmpty();
    }

    /**
     * 是有值的
     * @param value
     * @return
     */
    static boolean isValuable(Iterable<?> value) {
        return value != null && value.iterator().hasNext();
    }

    /**
     * 是否为空
     * @param value
     * @return
     */
    static boolean isEmpty(Object value) {
        if (value == null) {
            return true;
        }
        if (value instanceof CharSequence) {
            return ((CharSequence) value).length() == 0;
        }
        if (value instanceof Collection) {
            return ((Collection<?>) value).isEmpty();
        }
        if (value instanceof Map) {
            return ((Map<?,?>) value).isEmpty();
        }
        if (value.getClass().isArray()) {
            return ((Object[]) value).length == 0;
        }
        if (value instanceof Iterable) {
            return !((Iterable<?>) value).iterator().hasNext();
        }
        return false;
    }

    /**
     * 是否为空
     * @param value
     * @return
     */
    static boolean isEmpty(CharSequence value) {
        return value == null || value.length() == 0;
    }

    /**
     * 是否为空
     * @param value
     * @return
     */
    static <T>boolean isEmpty(T[] value) {
        return value == null || value.length == 0;
    }

    /**
     * 是否为空
     * @param value
     * @return
     */
    static boolean isEmpty(Collection<?> value) {
        return value == null || value.isEmpty();
    }

    /**
     * 是否为空
     * @param value
     * @return
     */
    static boolean isEmpty(Map<?, ?> value) {
        return value == null || value.isEmpty();
    }

    /**
     * 是否为空
     * @param value
     * @return
     */
    static boolean isEmpty(Iterable<?> value) {
        return value == null || !value.iterator().hasNext();
    }

}
